plot

Accurate and interative big data visualization
import holoviews as hv
import numpy as np
from decorrelation.cli.utils.logging import get_logger
Error.  nthreads cannot be larger than environment variable "NUMEXPR_MAX_THREADS" (64)

source

render_ras_tiles

 render_ras_tiles (ras:str, out_dir:str)

render raster data to tiles of difference zoom levels.

Type Details
ras str path to input data, 2D zarr array (one single raster) or 3D zarr array (a stack of rasters)
out_dir str output directory to store rendered data

render_ras_tiles render one single raster (2D array) or a stack of rasters (2D array) into tiles of difference resolution (zoom level).

adi = 'plot/adi.zarr'
rslc = 'plot/rslc.zarr'
rendered_adi_dir = 'plot/adi_tiles'
rendered_rslc_dir = 'plot/rslc_tiles'
logger = get_logger()
render_ras_tiles(adi,rendered_adi_dir)
2024-03-21 19:36:00 - logging_args - INFO - running function: render_ras_tiles
2024-03-21 19:36:00 - logging_args - INFO - fetching args:
2024-03-21 19:36:00 - logging_args - INFO - ras = 'plot/adi.zarr'
2024-03-21 19:36:00 - logging_args - INFO - out_dir = 'plot/adi_tiles'
2024-03-21 19:36:00 - logging_args - INFO - fetching args done.
2024-03-21 19:36:00 - zarr_info - INFO - plot/adi.zarr zarray shape: (2500, 1834)
2024-03-21 19:36:00 - zarr_info - INFO - plot/adi.zarr zarray chunks: (1000, 1000)
2024-03-21 19:36:00 - zarr_info - INFO - plot/adi.zarr zarray dtype: float32
2024-03-21 19:36:00 - render_ras_tiles - INFO - rendered tiles zoom level range from 0 (finest resolution) to 10 (coarsest resolution).
2024-03-21 19:36:00 - render_ras_tiles - INFO - tiles to be rendered: 
                       path         shape      chunks    dtype
0    plot/adi_tiles/0.zarr  (2500, 1834)  (256, 256)  float32
1    plot/adi_tiles/1.zarr   (1250, 917)  (256, 256)  float32
2    plot/adi_tiles/2.zarr    (625, 459)  (256, 256)  float32
3    plot/adi_tiles/3.zarr    (313, 230)  (256, 256)  float32
4    plot/adi_tiles/4.zarr    (157, 115)  (256, 256)  float32
5    plot/adi_tiles/5.zarr      (79, 58)  (256, 256)  float32
6    plot/adi_tiles/6.zarr      (40, 29)  (256, 256)  float32
7    plot/adi_tiles/7.zarr      (20, 15)  (256, 256)  float32
8    plot/adi_tiles/8.zarr       (10, 8)  (256, 256)  float32
9    plot/adi_tiles/9.zarr        (5, 4)  (256, 256)  float32
10  plot/adi_tiles/10.zarr        (3, 2)  (256, 256)  float32
2024-03-21 19:36:00 - render_ras_tiles - INFO - tiles rendering starts.
Tiles: 100%|██████████| 11/11 [00:00<00:00, 33.32it/s]
2024-03-21 19:36:01 - render_ras_tiles - INFO - tiles rendering finished.
render_ras_tiles(rslc,rendered_rslc_dir)
2024-03-21 19:36:01 - logging_args - INFO - running function: render_ras_tiles
2024-03-21 19:36:01 - logging_args - INFO - fetching args:
2024-03-21 19:36:01 - logging_args - INFO - ras = 'plot/rslc.zarr'
2024-03-21 19:36:01 - logging_args - INFO - out_dir = 'plot/rslc_tiles'
2024-03-21 19:36:01 - logging_args - INFO - fetching args done.
2024-03-21 19:36:01 - zarr_info - INFO - plot/rslc.zarr zarray shape: (2500, 1834, 17)
2024-03-21 19:36:01 - zarr_info - INFO - plot/rslc.zarr zarray chunks: (1000, 1000, 1)
2024-03-21 19:36:01 - zarr_info - INFO - plot/rslc.zarr zarray dtype: complex64
2024-03-21 19:36:01 - render_ras_tiles - INFO - rendered tiles zoom level range from 0 (finest resolution) to 10 (coarsest resolution).
2024-03-21 19:36:02 - render_ras_tiles - INFO - tiles to be rendered: 
                        path             shape         chunks      dtype
0    plot/rslc_tiles/0.zarr  (2500, 1834, 17)  (256, 256, 1)  complex64
1    plot/rslc_tiles/1.zarr   (1250, 917, 17)  (256, 256, 1)  complex64
2    plot/rslc_tiles/2.zarr    (625, 459, 17)  (256, 256, 1)  complex64
3    plot/rslc_tiles/3.zarr    (313, 230, 17)  (256, 256, 1)  complex64
4    plot/rslc_tiles/4.zarr    (157, 115, 17)  (256, 256, 1)  complex64
5    plot/rslc_tiles/5.zarr      (79, 58, 17)  (256, 256, 1)  complex64
6    plot/rslc_tiles/6.zarr      (40, 29, 17)  (256, 256, 1)  complex64
7    plot/rslc_tiles/7.zarr      (20, 15, 17)  (256, 256, 1)  complex64
8    plot/rslc_tiles/8.zarr       (10, 8, 17)  (256, 256, 1)  complex64
9    plot/rslc_tiles/9.zarr        (5, 4, 17)  (256, 256, 1)  complex64
10  plot/rslc_tiles/10.zarr        (3, 2, 17)  (256, 256, 1)  complex64
2024-03-21 19:36:02 - render_ras_tiles - INFO - tiles rendering starts.
Images: 100%|██████████| 17/17 [00:08<00:00,  1.90it/s]
2024-03-21 19:36:11 - render_ras_tiles - INFO - tiles rendering finished.

source

ras_plot

 ras_plot (rendered_tiles_dir:str, post_proc:Callable=None,
           bounds:tuple=None)

plot rendered ras tiles.

Type Default Details
rendered_tiles_dir str directory to the rendered images
post_proc Callable None function for the post processing
bounds tuple None bounding box (x0, y0, x_max, y_max)
hv.extension('bokeh')

ras_plot take the rendered tiles as the input and return a Holoviews DynamicMap. It accept a post processing function for customized post processing. Here we define a function to mask pixels with ADI larger than 0.4:

def mask_adi(data:np.array,):
    data[data>=0.4]=np.nan
    return data
adi_plot = ras_plot(rendered_adi_dir,post_proc=mask_adi,bounds=(0,0,1833,2499))

Add annotations:

adi_plot = adi_plot.redim(x=hv.Dimension('r', label='Range'), y=hv.Dimension('az',label='Azimuth'),
                          z=hv.Dimension('adi',label='Amplitude Dispersion Index',range=(0,0.4)))

Specify plotting options and plot:

adi_plot.opts(opts.Image(cmap='fire',width=600, height=400, colorbar=True,
                         invert_yaxis=True, tools=['hover'],))

source

ras_stack_plot

 ras_stack_plot (rendered_tiles_dir:str, post_proc:Callable=None,
                 bounds:tuple=None)

plot rendered stack of ras tiles.

Type Default Details
rendered_tiles_dir str directory to the rendered images
post_proc Callable None function for the post processing
bounds tuple None bounding box (x0, y0, x_max, y_max)

ras_stack_plot take the rendered images as the input and return a Holoviews DynamicMap. It accept a post processing function for customized post processing. Here we define a function to generate interferograms w.r.t the first SLC:

def intf_0(data_zarr, xslice, yslice,i):
    return np.angle(data_zarr[yslice,xslice,i]*data_zarr[yslice,xslice,0].conj())
intf_plot = ras_stack_plot(rendered_rslc_dir,post_proc=intf_0)

Add annotations:

dates = ["20210802", "20210816", "20210830", "20210913", "20211011", "20211025", "20220606", "20220620",
         "20220704", "20220718", "20220801", "20220815", "20220829", "20220912", "20220926", "20221010",
         "20221024",]
intf_plot = intf_plot.redim(i=hv.Dimension('i', label='Interferogram', range=(0,16), value_format=(lambda i: dates[i]+'_'+dates[0])),
                            x=hv.Dimension('r', label='Range'), y=hv.Dimension('az',label='Azimuth'), z=hv.Dimension('Phase',range=(-np.pi,np.pi)))

Specify plotting options and plot:

hv.output(widget_location='bottom')
intf_plot.opts(opts.Image(cmap='colorwheel',width=600, height=400, colorbar=True,
                          invert_yaxis=True, tools=['hover'],))

We can also plot sequential interferograms. In this case, we only plot 26 interferograms.

def intf_seq(data_zarr, xslice, yslice,i):
    return np.angle(data_zarr[yslice,xslice,i]*data_zarr[yslice,xslice,i-1].conj())
intf_plot = ras_stack_plot(rendered_rslc_dir,post_proc=intf_seq)
intf_plot = intf_plot.redim(i=hv.Dimension('i', label='Interferogram', range=(1,16), value_format=(lambda i: dates[i]+'_'+dates[i-1])),
                            x=hv.Dimension('r', label='Range'), y=hv.Dimension('az',label='Azimuth'), z=hv.Dimension('Phase',range=(-np.pi,np.pi)))
intf_plot.opts(opts.Image(cmap='colorwheel',width=600, height=400, colorbar=True,
                          invert_yaxis=True, tools=['hover'],))

Or the intensity:

def intensity(data_zarr, xslice, yslice,i):
    return np.log(np.abs(data_zarr[yslice,xslice,i])**2)

int_plot = ras_stack_plot(rendered_rslc_dir,post_proc=intensity)
int_plot = int_plot.redim(i=hv.Dimension('i', label='Intensity', range=(1,16), value_format=(lambda i: dates[i])),
                          x=hv.Dimension('r', label='Range'), y=hv.Dimension('az',label='Azimuth'), z=hv.Dimension('Intensity'))
int_plot.opts(opts.Image(cmap='fire',width=600, height=400, colorbar=True,
                          invert_yaxis=True, tools=['hover'],))